package cn.com.pc.content.config;

import cn.pconline.censor.client.cache.CacheClient;
import cn.pconline.censor.client.util.BaseConfig;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Configuration
public class BeanRegisterAutoConfig {

    public BeanRegisterAutoConfig(ApplicationContext applicationContext) {
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorAppDataSource", DriverManagerDataSource.class,
//                "prop|driverClassName|org.postgresql.Driver",
//                "prop|url|jdbc:postgresql://192.168.240.53:5432/censor_app",
//                "prop|username|censor_app",
//                "prop|password|Cheap4#xxxx");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorCategoryRepository", cn.pconline.censor.client.repository.CategoryRepository.class, "ref|dataSource|censorAppDataSource");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorLevelRepository", cn.pconline.censor.client.repository.LevelRepository.class, "ref|dataSource|censorAppDataSource");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorKeywordRepository", cn.pconline.censor.client.repository.KeywordRepository.class, "ref|dataSource|censorAppDataSource");
//        registerBean((ConfigurableApplicationContext)applicationContext, "censorCategoryService", cn.pconline.censor.client.service.CategoryService.class);
//        registerBean((ConfigurableApplicationContext)applicationContext, "censorLevelService", cn.pconline.censor.client.service.LevelService.class, "ref|levelRepository|censorLevelRepository");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorCacheClient", CacheClient.class);
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorBaseConfig", BaseConfig.class, "prop|memCacheName4csrData|csrDataLastUpdateAt", "prop|domain|pcauto");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorkeywordService", cn.pconline.censor.client.service.KeywordService.class, "init|init");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorkeywordServiceAuto", cn.pconline.censor.client.service.KeywordService.class, "init|init", "prop|domain|pcauto");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorkeywordServiceLady", cn.pconline.censor.client.service.KeywordService.class, "init|init", "prop|domain|pclady");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorkeywordServiceBaby", cn.pconline.censor.client.service.KeywordService.class, "init|init", "prop|domain|pcbaby");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorkeywordServiceHouse", cn.pconline.censor.client.service.KeywordService.class, "init|init", "prop|domain|pchouse");
//        registerBean((ConfigurableApplicationContext) applicationContext, "censorkeywordServiceGeeknev", cn.pconline.censor.client.service.KeywordService.class, "init|init", "prop|domain|geeknev");
    }

    public <T> T registerBean(ConfigurableApplicationContext applicationContext, String name, Class<T> clazz, String... args) {
        String init = "";
        String destroy = "";
        List constructorArgValues = new ArrayList();
        Map<String, Object> propertyValues = new HashMap();
        Map<String, String> propertyReferences = new HashMap();
        for (String arg : args) {
            String[] split = arg.split("|");
            if ("cons".equals(split[0])) {
                constructorArgValues.add(split[1]);
            } else if ("prop".equals(split[0])) {
                propertyValues.put(split[1], split[2]);
            } else if ("ref".equals(split[0])) {
                propertyReferences.put(split[1], split[2]);
            } else if ("init".equals(split[0])) {
                init = split[1];
            } else if("destr".equals(split[0])){
                destroy = split[1];
            }
        }
        return registerBean(applicationContext, name, clazz, init, destroy, constructorArgValues, propertyValues, propertyReferences);
    }


    public <T> T registerBean(ConfigurableApplicationContext applicationContext, String name, Class<T> clazz, String init, String destroy,
                              List constructorArgValues, Map<String, Object> propertyValues, Map<String, String> propertyReferences) {
        if (applicationContext.containsBean(name)) {
            Object bean = applicationContext.getBean(name);
            if (bean.getClass().isAssignableFrom(clazz)) {
                return (T) bean;
            } else {
                throw new RuntimeException("BeanName 重复 " + name);
            }
        }


        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        for (Object arg : constructorArgValues) {
            beanDefinitionBuilder.addConstructorArgValue(arg);
        }
        if (StringUtils.isNoneBlank(init)) {
            beanDefinitionBuilder.setInitMethodName(init);
        }
        if (StringUtils.isNoneBlank(destroy)) {
            beanDefinitionBuilder.setDestroyMethodName(destroy);
        }
        if (propertyValues != null) {
            for (String key : propertyValues.keySet()) {
                beanDefinitionBuilder.addPropertyValue(key, propertyValues.get(key));
            }
        }
        if (propertyReferences != null) {
            for (String key : propertyReferences.keySet()) {
                beanDefinitionBuilder.addPropertyReference(key, propertyReferences.get(key));
            }
        }
        BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();

        BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) applicationContext.getBeanFactory();
        beanFactory.registerBeanDefinition(name, beanDefinition);
        return applicationContext.getBean(name, clazz);
    }

//
//    <?xml version="1.0" encoding="GBK"?>
//<beans xmlns="http://www.springframework.org/schema/beans"
//    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
//    xmlns:context="http://www.springframework.org/schema/context"
//    xmlns:jee="http://www.springframework.org/schema/jee"
//    xmlns:util="http://www.springframework.org/schema/util"
//    xmlns:p="http://www.springframework.org/schema/p"
//    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
//    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
//    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
//    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
//
//    <!-- 审核平台的数据源 -->
//    <jee:jndi-lookup id="censorAppDataSource" jndi-name="jdbc/censor"/>
//
//    <!--bean id="censorAppDataSource"
//    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
//        <property name="driverClassName" value="org.postgresql.Driver"></property>
//        <property name="url" value="jdbc:postgresql://192.168.240.53:5432/censor_app"></property>
//        <property name="username" value="censor_app"></property>
//        <property name="password" value="Cheap4#xxxx"></property>
//    </bean -->
//
//    <bean id="censorCategoryRepository" class="cn.pconline.censor.client.repository.CategoryRepository"
//    p:dataSource-ref="censorAppDataSource"/>
//    <bean id="censorLevelRepository" class="cn.pconline.censor.client.repository.LevelRepository"
//    p:dataSource-ref="censorAppDataSource"/>
//    <bean id="censorKeywordRepository" class="cn.pconline.censor.client.repository.KeywordRepository"
//    p:dataSource-ref="censorAppDataSource"/>
//
//    <bean id="censorCategoryService" class="cn.pconline.censor.client.service.CategoryService"/>
//    <bean id="censorLevelService" class="cn.pconline.censor.client.service.LevelService" p:levelRepository-ref="censorLevelRepository"/>
//
//    <!-- 为了支持评论系统中按需调用不同网站关键词库的功能，如果不传domain参数的话，取censorBaseConfig中的domain值。此时只能按名称获得bean -->
//    <bean id="denyKeywordService" class="cn.pconline.bbs7.service.DenyKeywordService" init-method="init"/>
//    <bean id="censorKeywordService" class="cn.pconline.censor.client.service.KeywordService" init-method="init"/>
//    <bean id="censorKeywordServiceAuto" class="cn.pconline.censor.client.service.KeywordService" p:domain="pcauto" init-method="init"/>
//    <bean id="censorKeywordServiceGames" class="cn.pconline.censor.client.service.KeywordService" p:domain="pcgames" init-method="init"/>
//    <bean id="censorKeywordServiceLady" class="cn.pconline.censor.client.service.KeywordService" p:domain="pclady" init-method="init"/>
//    <bean id="censorKeywordServiceBaby" class="cn.pconline.censor.client.service.KeywordService" p:domain="pcbaby" init-method="init"/>
//    <bean id="censorKeywordServiceHouse" class="cn.pconline.censor.client.service.KeywordService" p:domain="pchouse" init-method="init"/>
//    <bean id="censorKeywordServiceGeeknev" class="cn.pconline.censor.client.service.KeywordService" p:domain="geeknev" init-method="init"/>
//    <bean id="censorCacheClient" class="cn.pconline.censor.client.cache.CacheClient" p:memCachedClient-ref="memCachedClient4RClient"/>
//    <bean id="censorBaseConfig" class="cn.pconline.censor.client.util.BaseConfig">
//        <property name="domain" value="pcauto" />
//        <property name="memCacheName4csrData" value="csrDataLastUpdateAt"/>
//    </bean>
//
//    <bean id="censorSystemTmpService" class="cn.pconline.bbs7.service.CensorSystemTmpService"
//    p:appName="pcauto_bbs6"
//    p:site="2"
//    p:clientUri="${censor.clientUri}"
//    p:censorDomain="${censor.censorDomain}"
//    p:censorIP="${censor.censorIP}"
//    p:simpleHttpTemplate4Censor-ref="simpleHttpTemplate4Censor"
//    init-method="init"
//    destroy-method="shutdown">
//    </bean>
//
//</beans>

}
